package com.culturalCenter.dataCenter.schedule.volunteer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.culturalCenter.dataCenter.Utils.ClassUtil;
import com.culturalCenter.dataCenter.Utils.MD5Util;
import com.culturalCenter.dataCenter.Utils.RedisUtil;
import com.culturalCenter.dataCenter.entity.volunteer.CdcVolunteer;
import com.culturalCenter.dataCenter.entity.volunteer.CdcVolunteerActivity;
import com.culturalCenter.dataCenter.entity.volunteer.CdcVolunteerSignuprecord;
import com.culturalCenter.dataCenter.mapper.volunteer.CdcVolunteerActivityMapper;
import com.culturalCenter.dataCenter.mapper.volunteer.CdcVolunteerMapper;
import com.culturalCenter.dataCenter.mapper.volunteer.CdcVolunteerSignuprecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 定时任务_志愿者
 *
 * @Author zhao
 * @Date 2021-9-17 9:13
 */
@Component
@Slf4j
@Async("dataThreadExecutor")
public class VolunteerDataPull {

    /**
     * 登录取OFA-TOKEN接口
     */
    private String loginUrl = "/api/ofa-admin/login";
    /**
     * 志愿者活动信息接口
     */
    private String volunteerInfoUrl = "/api/tcc-mes-service/volunteer/bigData/certificate/list";
    /**
     * 志愿者活动信息接口
     */
    private String volunteerActivityInfoUrl = "/api/tcc-mes-service/volunteer/bigData/activity/list";
    /**
     * 志愿者报名记录接口
     */
    private String volunteerSignUpUrl = "/api/tcc-mes-service/volunteer/bigData/register/list";
    @Value("${tuchuang.hostname}")
    private String hostname;
    @Value("${tuchuang.username}")
    private String username;
    @Value("${tuchuang.password}")
    private String password;
    @Value("${tuchuang.key}")
    private String key;
    @Value("${tuchuang.code}")
    private String code;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private RedissonClient redisson;
    @Resource
    private CdcVolunteerMapper cdcVolunteerMapper;
    @Resource
    private CdcVolunteerActivityMapper cdcVolunteerActivityMapper;
    @Resource
    private CdcVolunteerSignuprecordMapper cdcVolunteerSignuprecordMapper;
    private long volunteer_timestamp1;
    // private long volunteer_timestamp2;
//    private static String OFA_TOKEN;

    /**
     * 初始化时间戳
     */
    @PostConstruct
    public void initTimeStamp() {
        volunteer_timestamp1 = !redisUtil.redisTemplate.hasKey("volunteerTimestamp1") ? 0 : Long.parseLong(redisUtil.get("volunteerTimestamp1"));
        // volunteer_timestamp2 = !redisUtil.redisTemplate.hasKey("volunteerTimestamp2") ? 0 : Long.parseLong(redisUtil.get("volunteerTimestamp2"));

        // for test
        // volunteer_timestamp1 = 0;
        // volunteer_timestamp2 = 0;
        // for (int i = 1; i <= 3; i++) {
        //     redisUtil.del("volunteer_lock" + i);
        // }
    }

    /**
     * 调取图创登录接口获得OFA_TOKEN
     */
//    @PostConstruct
//    @Scheduled(cron = "0 */30 * * * ? ")
    public void getOFA_TOKEN() {
        String url = hostname + loginUrl;
        String encPassword = MD5Util.encode2hex(password);
        JSONObject param = new JSONObject();
        param.put("username", username);
        param.put("password", password);
        param.put("key",key);
        param.put("code",code);
        HttpEntity httpEntity = new HttpEntity(param);
        try {
            JSONObject result = restTemplate.postForObject(url, httpEntity, JSONObject.class);
            String data = result.getString("data");
            if(!data.isEmpty()) {
                redisUtil.set("OFA-TOKEN", result.getString("data"));
            }
//            OFA_TOKEN = result.getString("data");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 统一获取响应数据中的data
     *
     * @param url
     * @param param
     *
     * @return
     */
    public String getResponse(String url, Map<String, Object> param, boolean isReload) {
        String interfaceUrl = !param.isEmpty() ? (url + "?" + ClassUtil.setParamString(param)) : url;
        String data;
        String OFA_TOKEN = redisUtil.get("OFA-TOKEN");
        try {
            if (OFA_TOKEN != null) {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                headers.add("OFA-TOKEN", OFA_TOKEN);
                HttpEntity httpEntity = new HttpEntity(headers);
                ResponseEntity<String> responseEntity = restTemplate.exchange(interfaceUrl, HttpMethod.GET, httpEntity, String.class);
                JSONObject result = JSON.parseObject(responseEntity.getBody());
                data = result.getString("data");
            } else {
                String responseJson = restTemplate.getForObject(interfaceUrl, String.class, param);
                data = JSON.parseObject(responseJson).getString("data");
            }
            return data;
        } catch (HttpClientErrorException e) {
            log.error("TCC的Token失效，重新获取");
            getOFA_TOKEN();
            if (!isReload) {
                getResponse(url, param,true);
            }
            throw new RuntimeException("重新获取OFA-TOKEN");
        } catch (HttpServerErrorException e) {
            log.error("TCC综合管理平台服务端异常，请联系TCC相关人员");
            throw e;
        }
    }

    /**
     * 志愿者信息拉取（cdc_volunteer）
     */
    //@Scheduled(cron = "${cron.volunteerPull}")
//     @Scheduled(cron = "${cron.test}")
    public void pullVolunteer() {
        String lockKey = "volunteer_lock1";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("开始拉取cdc_volunteer");
            String url = hostname + volunteerInfoUrl;
            Map<String, Object> param = new HashMap<>();
            param.put("updateTimeStamp", volunteer_timestamp1);
            String data = getResponse(url, param,false);
            List<CdcVolunteer> volunteerList = JSONObject.parseArray(data, CdcVolunteer.class);
            if (CollectionUtils.isNotEmpty(volunteerList)) {
                int index = volunteerList.size() % 5000 == 0 ? volunteerList.size() / 5000 : volunteerList.size() / 5000 + 1;
                for (int i = 0; i < index; i++) {
                    cdcVolunteerMapper.insertOrUpdateBatch(volunteerList.stream().skip(i * 5000).limit(5000).collect(Collectors.toList()));
                }
                redisUtil.set("volunteer_timestamp1",
                        Long.toString(volunteerList.stream().max(Comparator.comparing(CdcVolunteer::getUpdateTime)).get().getUpdateTime().getTime()));
            }
            log.info("cdc_volunteer拉取完成");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

    /**
     * 志愿者活动信息拉取（cdc_volunteer_activity）
     */
//    @Scheduled(cron = "${cron.volunteerPull}")
//     @Scheduled(cron = "${cron.test}")
    public void pullVolunteerActivity() {
        String lockKey = "volunteer_lock2";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("开始拉取cdc_volunteer_activity");
            String url = hostname + volunteerActivityInfoUrl;
            Map<String, Object> param = new HashMap<>();
            //        param.put("updateTimeStamp", volunteer_timestamp2);
            String data = getResponse(url, param,false);
            List<CdcVolunteerActivity> volunteerActivityList = JSONObject.parseArray(data, CdcVolunteerActivity.class);
            if (CollectionUtils.isNotEmpty(volunteerActivityList)) {
                int index = volunteerActivityList.size() % 5000 == 0 ? volunteerActivityList.size() / 5000 : volunteerActivityList.size() / 5000 + 1;
                for (int i = 0; i < index; i++) {
                    cdcVolunteerActivityMapper.insertOrUpdateBatch(volunteerActivityList.stream().skip(i * 5000).limit(5000).collect(Collectors.toList()));
                }

                /*
                List updateList = volunteerActivityList.stream().filter(w -> w.getUpdateTime() != null).map(CdcVolunteerActivity::getUpdateTime).collect(Collectors.toList());
                volunteerActivityList.clear();
                if (CollectionUtils.isNotEmpty(updateList)) {
                    Date timeLatest = (Date) Collections.max(updateList);
                    volunteer_timestamp2 = timeLatest.getTime();
                    redisUtil.set("volunteer_timestamp2", Long.toString(volunteer_timestamp2));
                }*/
            }
            log.info("cdc_volunteer_activity拉取完成");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

    /**
     * 志愿者报名记录拉取（cdc_volunteer_signUpRecord）
     */
//    @Scheduled(cron = "${cron.volunteerPull}")
//     @Scheduled(cron = "${cron.test}")
    public void pullVolunteerSignUpRecord() {
        String lockKey = "volunteer_lock3";
        RLock redissonLock = redisson.getLock(lockKey);
        try {
            boolean locked = redissonLock.isLocked();
            if (!locked){
                redissonLock.lock();
            }
            log.info("开始拉取cdc_volunteer_signUpRecord");
            String url = hostname + volunteerSignUpUrl;
            Map<String, Object> param = new HashMap<>();
            String data = getResponse(url, param,false);
            List<CdcVolunteerSignuprecord> volunteerSignUpList = JSONObject.parseArray(data, CdcVolunteerSignuprecord.class);
            if (CollectionUtils.isNotEmpty(volunteerSignUpList)) {
                int index = volunteerSignUpList.size() % 5000 == 0 ? volunteerSignUpList.size() / 5000 : volunteerSignUpList.size() / 5000 + 1;
                for (int i = 0; i < index; i++) {
                    cdcVolunteerSignuprecordMapper.insertOrUpdateBatch(volunteerSignUpList.stream().skip(i * 5000).limit(5000).collect(Collectors.toList()));
                }
            }
            log.info("cdc_volunteer_signUpRecord拉取完成");
        } finally {
            boolean locked = redissonLock.isLocked();
            if (locked){
                redissonLock.unlock();
            }
        }
    }

}
